package com.yanqu.road.server.gameplayer.module.player;

import com.yanqu.road.entity.enums.eBlacklistType;
import com.yanqu.road.entity.player.UserBlacklist;
import com.yanqu.road.logic.bussiness.player.BlacklistBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.marriage.CrossMarriageProto;
import com.yanqu.road.pb.player.BlacklistProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.module.creditpoints.CreditPointsModule;
import com.yanqu.road.server.manger.marriage.MarriageMgr;
import com.yanqu.road.server.manger.player.BlacklistMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.wingroom.WingRoomMessageMgr;
import com.yanqu.road.server.pb.BlacklistPb;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.TimeHelper;
import com.yanqu.road.utils.YanQuMessageUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 黑名单模块
 */
public class BlacklistModule extends GeneralModule {
    public BlacklistModule(GamePlayer player) {
        super(player);
    }

    private Map<Integer, Map<Long, UserBlacklist>> userBlacklistMap;
    private Map<Integer, Map<Long, Map<Long, UserBlacklist>>> crossUserBlacklistMap;

    @Override
    public boolean loadData() {
        userBlacklistMap = BlacklistBussiness.getUserBlacklistMap(player.getUserId());
        BlacklistMgr.putPlayerBlacklistMap(player.getUserId(), userBlacklistMap);
        for(Map<Long, UserBlacklist> typeMap : userBlacklistMap.values()) {
            for (UserBlacklist userBlacklist : typeMap.values()) {
                userBlacklist.setBlacklistUserServerId(GameServer.getInstance().getServerId());
            }
        }
        crossUserBlacklistMap = BlacklistBussiness.getCrossUserBlacklistMap(player.getUserId());
        BlacklistMgr.putPlayerCrossBlacklistMap(player.getUserId(), crossUserBlacklistMap);
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        for(Map<Long, UserBlacklist> dataMap : userBlacklistMap.values()) {
            for (UserBlacklist userBlacklist : dataMap.values()) {
                if (userBlacklist.isInsertOption()) {
                    BlacklistBussiness.addUserBlacklist(userBlacklist);
                } else if (userBlacklist.isUpdateOption()) {
                    BlacklistBussiness.updateUserBlacklist(userBlacklist);
                }
            }
        }
        for(Map<Long, Map<Long, UserBlacklist>> typeMap : crossUserBlacklistMap.values()) {
            for (Map<Long, UserBlacklist> dataMap : typeMap.values()) {
                for (UserBlacklist userBlacklist : dataMap.values()) {
                    if (userBlacklist.isInsertOption()) {
                        BlacklistBussiness.addCrossUserBlacklist(userBlacklist);
                    } else if (userBlacklist.isUpdateOption()) {
                        BlacklistBussiness.updateCrossUserBlacklist(userBlacklist);
                    }
                }
            }
        }
        return true;
    }

    @Override
    public void loginSendMsg() {
        syncBlacklist(getUserBlacklistList(), true);
    }

    private List<UserBlacklist> getUserBlacklistList(){
        List<UserBlacklist> dataList = new ArrayList<>();
        for(Map<Long, UserBlacklist> dataMap : userBlacklistMap.values()) {
            for (UserBlacklist userBlacklist : dataMap.values()) {
                if (!userBlacklist.isDelete()) {
                    dataList.add(userBlacklist);
                }
            }
        }
        for(Map<Long, Map<Long, UserBlacklist>> serverMap : crossUserBlacklistMap.values()) {
            for (Map<Long, UserBlacklist> dataMap : serverMap.values()) {
                for (UserBlacklist userBlacklist : dataMap.values()) {
                    if (!userBlacklist.isDelete()) {
                        dataList.add(userBlacklist);
                    }
                }
            }
        }
        return dataList;
    }

    public void syncBlacklist(UserBlacklist userBlacklist){
        if(null != userBlacklist){
            List<UserBlacklist> syncList = new ArrayList<>();
            syncList.add(userBlacklist);
            syncBlacklist(syncList, false);
        }
    }

    private void syncBlacklist(List<UserBlacklist> userBlacklistList, boolean isLogin){
        if(isLogin){
            player.sendPacket(Protocol.U_BLACKLIST_LIST, BlacklistPb.parseBlacklistListMsg(userBlacklistList));
        }else {
            player.sendPacket(Protocol.U_BLACKLIST_SYNC, BlacklistPb.parseBlacklistListMsg(userBlacklistList));
        }
    }

    /**
     * 设置黑名单
     *
     * @param blacklistUserId
     * @param blacklistUserServerId
     * @return
     */
    public synchronized int addBlacklist(int type, long blacklistUserId, long blacklistUserServerId){
        List<UserBlacklist> dataList = getUserBlacklistList();
        if(dataList.size() >= GameConfig.BLACKLIST_MAX_COUNT){
            return GameErrorCode.E_BLACKLIST_COUNT_OVER;
        }
        if (blacklistUserServerId == GameServer.getInstance().getServerId()) {
            if(!userBlacklistMap.containsKey(type)){
                userBlacklistMap.put(type, new ConcurrentHashMap<>());
            }
            Map<Long, UserBlacklist> dataMap = userBlacklistMap.get(type);
            UserBlacklist userBlacklist = dataMap.get(blacklistUserId);
            // 今日是否已拉黑
            List<Integer> typeList = new ArrayList<>();
            typeList.add(eBlacklistType.Chat.getValue());
            typeList.add(eBlacklistType.WingRoom.getValue());
            typeList.add(eBlacklistType.Marriage.getValue());
            typeList.remove(Integer.valueOf(type));
            boolean todayAlreadyAddBlacklist = false;
            if(null == userBlacklist){
                userBlacklist = new UserBlacklist();
                userBlacklist.setUserId(player.getUserId());
                userBlacklist.setBlacklistUserId(blacklistUserId);
                userBlacklist.setBlacklistUserServerId(GameServer.getInstance().getServerId());
                userBlacklist.setDelete(false);
                userBlacklist.setType(type);
                userBlacklist.setLastAddBlackListTime(System.currentTimeMillis());
                userBlacklist.setInsertOption();
                dataMap.put(blacklistUserId, userBlacklist);
            }else {
                userBlacklist.setDelete(false);
                todayAlreadyAddBlacklist = TimeHelper.dateCompare(userBlacklist.getLastAddBlackListTime());
                userBlacklist.setLastAddBlackListTime(System.currentTimeMillis());
            }
            if(!todayAlreadyAddBlacklist){
                for(int otherType : typeList){
                    UserBlacklist data = getUserBlacklist(otherType, blacklistUserId);
                    if(null != data){
                        todayAlreadyAddBlacklist = TimeHelper.dateCompare(data.getLastAddBlackListTime());
                        if(todayAlreadyAddBlacklist){
                            break;
                        }
                    }
                }
            }
            // 本服玩家举报增加不良信用积分
            if (!todayAlreadyAddBlacklist) {
                GamePlayer targetPlayer = GamePlayerMgr.getPlayer(blacklistUserId);
                if (targetPlayer != null) {
                    targetPlayer.getModule(CreditPointsModule.class).addCreditPoints(player.getTitleId());
                }
            }
            syncBlacklist(userBlacklist);
            if(eBlacklistType.WingRoom.getValue() == type) {
                //处理厢房本服留言板
                WingRoomMessageMgr.blacklistRemoveMessage(player.getUserId(), blacklistUserId, blacklistUserServerId);
            }else if(eBlacklistType.Marriage.getValue() == type) {
                //处理本服指向联姻
                MarriageMgr.blacklistRemoveAppointMarriage(player.getUserId(), blacklistUserId, blacklistUserServerId);
            }
            BlacklistProto.BlacklistAddRespMsg.Builder respMsg = BlacklistProto.BlacklistAddRespMsg.newBuilder();
            respMsg.setRet(0);
            respMsg.setBlacklistUserId(blacklistUserId);
            respMsg.setBlacklistUserServerId(blacklistUserServerId);
            respMsg.setType(type);
            player.sendPacket(Protocol.U_BLACKLIST_ADD, respMsg);
        } else {
            BlacklistProto.BlacklistAddCrossReqMsg.Builder crossMsg = BlacklistProto.BlacklistAddCrossReqMsg.newBuilder();
            crossMsg.setUserId(blacklistUserId);
            crossMsg.setServerId(blacklistUserServerId);
            crossMsg.setType(type);
            YanQuMessage yqMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_ADD_BLACK_LIST_GET_USER_INFO, crossMsg);
            GamePlayerMgr.sendPacket(player.getUserId(), yqMsg);
        }
        return 0;
    }

    /**
     * 取消黑名单
     *
     * @param blacklistUserId
     * @param blacklistUserServerId
     * @return
     */
    public int cancelBlacklist(int type, long blacklistUserId, long blacklistUserServerId){
        UserBlacklist userBlacklist = null;
        if (blacklistUserServerId == GameServer.getInstance().getServerId()) {
            Map<Long, UserBlacklist> dataMap = userBlacklistMap.get(type);
            if(null != dataMap) {
                userBlacklist = dataMap.get(blacklistUserId);
                if (null != userBlacklist) {
                    userBlacklist.setDelete(true);
                }
            }
        } else {
            Map<Long, Map<Long, UserBlacklist>> serverMap = crossUserBlacklistMap.get(type);
            if(null != serverMap) {
                Map<Long, UserBlacklist> dataMap = serverMap.get(blacklistUserServerId);
                if(null != dataMap){
                    userBlacklist = dataMap.get(blacklistUserId);
                    if (null != userBlacklist) {
                        userBlacklist.setDelete(true);
                    }
                }
            }
        }
        if (null != userBlacklist) {
            syncBlacklist(userBlacklist);
        }
        return 0;
    }

    public synchronized int addCrossBlacklist(int type, PlayerProto.PlayerBaseTempMsg baseUserInfo, long blacklistUserId) {
        List<UserBlacklist> dataList = getUserBlacklistList();
        if(dataList.size() >= GameConfig.BLACKLIST_MAX_COUNT){
            return GameErrorCode.E_BLACKLIST_COUNT_OVER;
        }
        if(!crossUserBlacklistMap.containsKey(type)){
            crossUserBlacklistMap.put(type, new ConcurrentHashMap<>());
        }
        Map<Long, Map<Long, UserBlacklist>> serverMap = crossUserBlacklistMap.get(type);
        long blacklistUserServerId = baseUserInfo.getServerId();
        if(!serverMap.containsKey(blacklistUserServerId)){
            serverMap.put(blacklistUserServerId, new ConcurrentHashMap<>());
        }
        Map<Long, UserBlacklist> dataMap = serverMap.get(blacklistUserServerId);
        UserBlacklist userBlacklist = dataMap.get(blacklistUserId);
        if (null == userBlacklist) {
            userBlacklist = new UserBlacklist();
            userBlacklist.setBlacklistUserServerId(blacklistUserServerId);
            userBlacklist.setUserId(player.getUserId());
            userBlacklist.setDelete(false);
            userBlacklist.setBlacklistUserId(blacklistUserId);
            userBlacklist.setUserBaseInfo(PlayerBasePb.parseBaseUserInfo(baseUserInfo));
            userBlacklist.setType(type);
            userBlacklist.setInsertOption();
            dataMap.put(blacklistUserId, userBlacklist);
        } else {
            userBlacklist.setUserBaseInfo(PlayerBasePb.parseBaseUserInfo(baseUserInfo));
            userBlacklist.setDelete(false);
        }
        syncBlacklist(userBlacklist);
        //黑名单其他处理
        blacklistDeal(type, blacklistUserId, blacklistUserServerId);
        return 0;
    }

    /**
    * 描述：黑名单其他模块处理
    * 作者：zrq
    * 时间：2023/1/3
    * 参数：

    * 返回值：
    **/
    private void blacklistDeal(int type, long blacklistUserId, long blacklistUserServerId){
        if(eBlacklistType.WingRoom.getValue() == type) {
            //处理厢房跨服服留言板
            WingRoomMessageMgr.blacklistRemoveMessage(player.getUserId(), blacklistUserId, blacklistUserServerId);
        }else if(eBlacklistType.Marriage.getValue() == type) {
            //处理跨服服指向联姻
            CrossMarriageProto.CrossMarriageBlacklistRemoveAppointReqMsg.Builder crossMsg = CrossMarriageProto.CrossMarriageBlacklistRemoveAppointReqMsg.newBuilder();
            crossMsg.setBlacklistUserId(blacklistUserId);
            crossMsg.setBlacklistServerId(blacklistUserServerId);
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_MARRIAGE_BLACKLIST_REMOVE_APPOINT, crossMsg);
            GamePlayerMgr.sendPacket(player.getUserId(), pbMsg);
        }
    }

    private UserBlacklist getUserBlacklist(int type, long blacklistUserId){
        Map<Long, UserBlacklist> dataMap = userBlacklistMap.get(type);
        if(null == dataMap){
            return null;
        }
        return dataMap.get(blacklistUserId);
    }
}
